home *** CD-ROM | disk | FTP | other *** search
- #include <unistd.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- #include "sg_lib.h"
- #include "sg_pt.h"
-
- /* This is a simple program executing a SCSI INQUIRY command and a
- TEST UNIT READY command using the SCSI generic pass through
- interface. This allows this example program to be ported to
- OSes other than linux.
-
- * Copyright (C) 2006-2007 D. Gilbert
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
-
- Invocation: sg_simple5 [-x] <scsi_device>
-
- Version 1.01 (20070331)
-
- */
-
- #define INQ_REPLY_LEN 96
- #define INQ_CMD_LEN 6
- #define TUR_CMD_LEN 6
-
- #define CMD_TIMEOUT_SECS 60
-
-
- int main(int argc, char * argv[])
- {
- int sg_fd, k, ok, dsize, res, duration, resid, cat, got, slen;
- unsigned char inqCmdBlk [INQ_CMD_LEN] =
- {0x12, 0, 0, 0, INQ_REPLY_LEN, 0};
- unsigned char turCmdBlk [TUR_CMD_LEN] =
- {0x00, 0, 0, 0, 0, 0};
- unsigned char inqBuff[INQ_REPLY_LEN];
- char * file_name = 0;
- char b[512];
- unsigned char sense_b[32];
- int verbose = 0;
- struct sg_pt_base * ptvp;
-
- for (k = 1; k < argc; ++k) {
- if (0 == strcmp("-v", argv[k]))
- verbose = 1;
- else if (0 == strcmp("-vv", argv[k]))
- verbose = 2;
- else if (0 == strcmp("-vvv", argv[k]))
- verbose = 3;
- else if (*argv[k] == '-') {
- printf("Unrecognized switch: %s\n", argv[k]);
- file_name = 0;
- break;
- }
- else if (0 == file_name)
- file_name = argv[k];
- else {
- printf("too many arguments\n");
- file_name = 0;
- break;
- }
- }
- if (0 == file_name) {
- printf("Usage: 'sg_simple5 [-v|-vv|-vvv] <device>'\n");
- return 1;
- }
-
- sg_fd = scsi_pt_open_device(file_name, 1 /* ro */, 0);
- /* N.B. An access mode of O_RDWR is required for some SCSI commands */
- if (sg_fd < 0) {
- fprintf(stderr, "error opening file: %s: %s\n",
- file_name, safe_strerror(-sg_fd));
- return 1;
- }
-
- dsize = sizeof(inqBuff);
- ok = 0;
-
- ptvp = construct_scsi_pt_obj(); /* one object per command */
- if (NULL == ptvp) {
- fprintf(stderr, "sg_simple5: out of memory\n");
- return -1;
- }
- set_scsi_pt_cdb(ptvp, inqCmdBlk, sizeof(inqCmdBlk));
- set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
- set_scsi_pt_data_in(ptvp, inqBuff, dsize);
- res = do_scsi_pt(ptvp, sg_fd, CMD_TIMEOUT_SECS, verbose);
- if (res < 0) {
- fprintf(stderr, " pass through os error: %s\n",
- safe_strerror(-res));
- goto finish_inq;
- } else if (SCSI_PT_DO_BAD_PARAMS == res) {
- fprintf(stderr, " bad pass through setup\n");
- goto finish_inq;
- } else if (SCSI_PT_DO_TIMEOUT == res) {
- fprintf(stderr, " pass through timeout\n");
- goto finish_inq;
- }
- if ((verbose > 1) && ((duration = get_scsi_pt_duration_ms(ptvp)) >= 0))
- fprintf(stderr, " duration=%d ms\n", duration);
- resid = get_scsi_pt_resid(ptvp);
- switch ((cat = get_scsi_pt_result_category(ptvp))) {
- case SCSI_PT_RESULT_GOOD:
- got = dsize - resid;
- if (verbose && (resid > 0))
- fprintf(stderr, " requested %d bytes but "
- "got %d bytes)\n", dsize, got);
- break;
- case SCSI_PT_RESULT_STATUS: /* other than GOOD and CHECK CONDITION */
- if (verbose) {
- sg_get_scsi_status_str(get_scsi_pt_status_response(ptvp),
- sizeof(b), b);
- fprintf(stderr, " scsi status: %s\n", b);
- }
- goto finish_inq;
- case SCSI_PT_RESULT_SENSE:
- slen = get_scsi_pt_sense_len(ptvp);
- if (verbose) {
- sg_get_sense_str("", sense_b, slen, (verbose > 1),
- sizeof(b), b);
- fprintf(stderr, "%s", b);
- }
- if (verbose && (resid > 0)) {
- got = dsize - resid;
- if ((verbose) || (got > 0))
- fprintf(stderr, " requested %d bytes but "
- "got %d bytes\n", dsize, got);
- }
- goto finish_inq;
- case SCSI_PT_RESULT_TRANSPORT_ERR:
- if (verbose) {
- get_scsi_pt_transport_err_str(ptvp, sizeof(b), b);
- fprintf(stderr, " transport: %s", b);
- }
- goto finish_inq;
- case SCSI_PT_RESULT_OS_ERR:
- if (verbose) {
- get_scsi_pt_os_err_str(ptvp, sizeof(b), b);
- fprintf(stderr, " os: %s", b);
- }
- goto finish_inq;
- default:
- fprintf(stderr, " unknown pass through result "
- "category (%d)\n", cat);
- goto finish_inq;
- }
-
- ok = 1;
- finish_inq:
- destruct_scsi_pt_obj(ptvp);
-
- if (ok) { /* output result if it is available */
- char * p = (char *)inqBuff;
-
- printf("Some of the INQUIRY command's results:\n");
- printf(" %.8s %.16s %.4s\n", p + 8, p + 16, p + 32);
- }
- ok = 0;
-
-
- /* Now prepare TEST UNIT READY command */
- ptvp = construct_scsi_pt_obj(); /* one object per command */
- if (NULL == ptvp) {
- fprintf(stderr, "sg_simple5: out of memory\n");
- return -1;
- }
- set_scsi_pt_cdb(ptvp, turCmdBlk, sizeof(turCmdBlk));
- set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
- /* no data in or out */
- res = do_scsi_pt(ptvp, sg_fd, CMD_TIMEOUT_SECS, verbose);
- if (res < 0) {
- fprintf(stderr, " pass through os error: %s\n",
- safe_strerror(-res));
- goto finish_inq;
- } else if (SCSI_PT_DO_BAD_PARAMS == res) {
- fprintf(stderr, " bad pass through setup\n");
- goto finish_inq;
- } else if (SCSI_PT_DO_TIMEOUT == res) {
- fprintf(stderr, " pass through timeout\n");
- goto finish_inq;
- }
- if ((verbose > 1) && ((duration = get_scsi_pt_duration_ms(ptvp)) >= 0))
- fprintf(stderr, " duration=%d ms\n", duration);
- resid = get_scsi_pt_resid(ptvp);
- switch ((cat = get_scsi_pt_result_category(ptvp))) {
- case SCSI_PT_RESULT_GOOD:
- break;
- case SCSI_PT_RESULT_STATUS: /* other than GOOD and CHECK CONDITION */
- if (verbose) {
- sg_get_scsi_status_str(get_scsi_pt_status_response(ptvp),
- sizeof(b), b);
- fprintf(stderr, " scsi status: %s\n", b);
- }
- goto finish_tur;
- case SCSI_PT_RESULT_SENSE:
- slen = get_scsi_pt_sense_len(ptvp);
- if (verbose) {
- sg_get_sense_str("", sense_b, slen, (verbose > 1),
- sizeof(b), b);
- fprintf(stderr, "%s", b);
- }
- goto finish_tur;
- case SCSI_PT_RESULT_TRANSPORT_ERR:
- if (verbose) {
- get_scsi_pt_transport_err_str(ptvp, sizeof(b), b);
- fprintf(stderr, " transport: %s", b);
- }
- goto finish_tur;
- case SCSI_PT_RESULT_OS_ERR:
- if (verbose) {
- get_scsi_pt_os_err_str(ptvp, sizeof(b), b);
- fprintf(stderr, " os: %s", b);
- }
- goto finish_tur;
- default:
- fprintf(stderr, " unknown pass through result "
- "category (%d)\n", cat);
- goto finish_tur;
- }
-
- ok = 1;
- finish_tur:
- destruct_scsi_pt_obj(ptvp);
-
- if (ok)
- printf("Test Unit Ready successful so unit is ready!\n");
- else
- printf("Test Unit Ready failed so unit may _not_ be ready!\n");
-
- scsi_pt_close_device(sg_fd);
- return 0;
- }
-